# Bazel build
# C/C++ documentation: https://docs.bazel.build/versions/master/be/c-cpp.html

load("//bazel:python.bzl", "py_test_module_list")
load("//bazel:ray.bzl", "COPTS")

cc_binary(
    name = "libray_api.so",
    copts = COPTS,
    linkopts = select({
        "@platforms//os:osx": [
            #TODO(larry): Hide the symbols when we make it work on mac.
        ],
        "@platforms//os:windows": [
            #TODO(larry): Hide the symbols when we make it work on Windows.
        ],
        "//conditions:default": [
            "-Wl,--version-script,$(location :symbols/ray_api_exported_symbols_linux.lds)",
        ],
    }),
    linkshared = 1,
    linkstatic = 1,
    visibility = ["//visibility:public"],
    deps = [
        ":ray_api_lib",
        ":symbols/ray_api_exported_symbols_linux.lds",
    ],
)

cc_library(
    name = "ray_api_lib",
    srcs = glob([
        "src/ray/api.cc",
        "src/ray/api/*.cc",
        "src/ray/api/*.h",
        "src/ray/app/*.cc",
        "src/ray/app/*.h",
        "src/ray/runtime/*.cc",
        "src/ray/runtime/*.h",
        "src/ray/runtime/**/*.cc",
        "src/ray/runtime/**/*.h",
        "src/ray/runtime/task/*.cc",
        "src/ray/runtime/task/*.h",
        "src/ray/util/*.cc",
        "src/ray/util/*.h",
        "src/ray/*.cc",
        "src/ray/*.h",
    ]),
    hdrs = glob([
        "include/ray/*.h",
        "include/ray/**/*.h",
        "include/ray/**/**/*.h",
    ]),
    copts = COPTS,
    linkopts = ["-ldl"],
    linkstatic = True,
    strip_include_prefix = "include",
    visibility = ["//visibility:public"],
    deps = [
        "//:ray_common",
        "//src/ray/core_worker:core_worker_lib",
        "//src/ray/gcs/gcs_client:global_state_accessor_lib",
        "//src/ray/util",
        "//src/ray/util:cmd_line_utils",
        "//src/ray/util:process",
        "@boost//:callable_traits",
        "@boost//:dll",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/flags:parse",
        "@msgpack",
        "@nlohmann_json",
    ],
    alwayslink = True,
)

cc_library(
    name = "ray_cpp_lib",
    srcs = [
        "libray_api.so",
    ],
    hdrs = glob([
        "include/ray/*.h",
        "include/ray/**/*.h",
        "include/ray/**/**/*.h",
    ]),
    strip_include_prefix = "include",
    visibility = ["//visibility:public"],
)

cc_binary(
    name = "default_worker",
    srcs = glob([
        "src/ray/worker/default_worker.cc",
    ]),
    copts = COPTS,
    linkstatic = True,
    deps = select({
        "@platforms//os:windows": [
            # TODO(SongGuyang): Change to use dynamic library
            # "ray_cpp_lib" when we make it work on Windows.
            "ray_api_lib",
        ],
        "//conditions:default": [
            "ray_cpp_lib",
            "@boost//:callable_traits",
            "@boost//:optional",
            "@msgpack",
            "@nlohmann_json",
        ],
    }),
)

filegroup(
    name = "ray_cpp_pkg_files",
    srcs = [
        "default_worker",
        "libray_api.so",
    ],
    visibility = ["//visibility:private"],
)

genrule(
    name = "ray_cpp_pkg",
    srcs = [
        "default_worker",
        "libray_api.so",
    ],
    outs = ["ray_cpp_pkg.out"],
    cmd = """
        WORK_DIR="$$(pwd)" &&
        PY_CPP_DIR="$$WORK_DIR/python/ray/cpp" &&
        rm -rf $$PY_CPP_DIR &&
        BOOST_DIR="$$PY_CPP_DIR/include/boost/" &&
        mkdir -p "$$BOOST_DIR" &&
        mkdir -p "$$PY_CPP_DIR/lib/" &&
        cp -f $(location default_worker) "$$PY_CPP_DIR/" &&
        cp -f -r $$WORK_DIR/external/msgpack/include/* "$$PY_CPP_DIR/include" &&
        cp -f -r $$WORK_DIR/external/nlohmann_json/single_include/* "$$PY_CPP_DIR/include" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/archive" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/assert" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/bind" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/callable_traits" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/concept" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/config" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/container" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/container_hash" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/core" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/detail" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/dll" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/exception" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/filesystem" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/functional" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/io" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/iterator" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/lexical_cast" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/move" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/mpl" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/optional" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/parameter" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/preprocessor" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/system" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/type_traits" "$$BOOST_DIR" &&
        cp -f -r "$$WORK_DIR/external/boost/boost/utility" "$$BOOST_DIR" &&
        cp -f -r $$WORK_DIR/external/boost/boost/*.hpp "$$BOOST_DIR" &&
        cp -f $(locations libray_api.so) "$$PY_CPP_DIR/lib/" &&
        cp -f -r "$$WORK_DIR/cpp/include/ray" "$$PY_CPP_DIR/include" &&
        THIRDPARTY_DIR="$$WORK_DIR/cpp/example/thirdparty" &&
        rm -rf $$THIRDPARTY_DIR &&
        mkdir $$THIRDPARTY_DIR &&
        cp -f -r "$$PY_CPP_DIR/include" $$THIRDPARTY_DIR &&
        cp -f -r "$$PY_CPP_DIR/lib" $$THIRDPARTY_DIR &&
        cp -f -r "$$WORK_DIR/cpp/example" "$$PY_CPP_DIR" &&
        echo "$$WORK_DIR" > $@
    """,
    local = 1,
    visibility = ["//visibility:private"],
)

# test
cc_test(
    name = "api_test",
    srcs = glob([
        "src/ray/test/*.cc",
    ]),
    copts = COPTS,
    linkstatic = True,
    tags = ["team:core"],
    deps = [
        "ray_api_lib",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "cluster_mode_test",
    srcs = glob(
        [
            "src/ray/test/cluster/*.cc",
            "src/ray/test/cluster/*.h",
        ],
        exclude = [
            "src/ray/test/cluster/cluster_mode_xlang_test.cc",
        ],
    ),
    args = [
        "--ray_code_search_path=$(location plus.so):$(location counter.so):cpp/src/ray/test/cluster",
        "--ray_head_args '--include-dashboard false'",
    ],
    copts = COPTS,
    data = [
        "counter.so",
        "plus.so",
        "src/ray/test/cluster/test_cross_language_invocation.py",
        ":ray_cpp_pkg_files",
    ],
    linkstatic = True,
    tags = ["team:core"],
    deps = [
        "ray_api_lib",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_test(
    name = "cluster_mode_xlang_test",
    srcs = glob([
        "src/ray/test/cluster/cluster_mode_xlang_test.cc",
        "src/ray/test/cluster/*.h",
    ]),
    args = [
        "--ray_code_search_path=$(location //java:libio_ray_ray_test.jar)",
        "--ray_head_args '--include-dashboard false'",
    ],
    copts = COPTS,
    data = [
        ":ray_cpp_pkg_files",
        "//java:libio_ray_ray_test.jar",
    ],
    linkstatic = True,
    tags = ["team:core"],
    deps = [
        "ray_api_lib",
        "@com_google_googletest//:gtest_main",
    ],
)

cc_binary(
    name = "plus.so",
    testonly = True,
    srcs = [
        "src/ray/test/cluster/plus.cc",
        "src/ray/test/cluster/plus.h",
    ],
    copts = COPTS,
    linkopts = ["-shared"],
    linkstatic = True,
    # NOTE(WangTaoTheTonic): For java x-lang tests. See //java:all_tests
    # and `CrossLanguageInvocationTest.java`.
    visibility = ["//java:__subpackages__"],
    deps = [
        "ray_cpp_lib",
        "@boost//:callable_traits",
        "@boost//:optional",
        "@msgpack",
        "@nlohmann_json",
    ],
)

cc_binary(
    name = "counter.so",
    testonly = True,
    srcs = [
        "src/ray/test/cluster/counter.cc",
        "src/ray/test/cluster/counter.h",
    ],
    copts = COPTS,
    linkopts = ["-shared"],
    linkstatic = True,
    # NOTE(WangTaoTheTonic): For java x-lang tests. See //java:all_tests
    # and `CrossLanguageInvocationTest.java`.
    visibility = ["//java:__subpackages__"],
    deps = [
        "ray_cpp_lib",
        "@boost//:callable_traits",
        "@boost//:optional",
        "@msgpack",
        "@nlohmann_json",
    ],
)

cc_test(
    name = "simple_kv_store",
    srcs = glob([
        "src/ray/test/examples/simple_kv_store.cc",
    ]),
    args = [
        "--ray_code_search_path=$(location simple_kv_store.so)",
        "--ray_head_args '--include-dashboard false'",
    ],
    copts = COPTS,
    data = [
        "simple_kv_store.so",
    ],
    linkstatic = True,
    tags = ["team:core"],
    deps = [
        "ray_api_lib",
    ],
)

cc_binary(
    name = "simple_kv_store.so",
    testonly = True,
    srcs = glob([
        "src/ray/test/examples/simple_kv_store.cc",
    ]),
    copts = COPTS,
    linkopts = ["-shared"],
    linkstatic = True,
    deps = [
        "ray_cpp_lib",
        "@boost//:callable_traits",
        "@boost//:optional",
        "@msgpack",
        "@nlohmann_json",
    ],
)

cc_binary(
    name = "simple_job",
    srcs = [
        "src/ray/test/examples/simple_job.cc",
    ],
    copts = COPTS,
    data = [
        "simple_job.so",
    ],
    linkstatic = True,
    tags = ["team:core"],
    deps = [
        ":ray_api_lib",
    ],
)

cc_binary(
    name = "simple_job.so",
    srcs = [
        "src/ray/test/examples/simple_job.cc",
    ],
    copts = COPTS,
    linkopts = ["-shared"],
    linkstatic = True,
    deps = [
        "ray_cpp_lib",
        "@boost//:callable_traits",
        "@boost//:optional",
        "@msgpack",
        "@nlohmann_json",
    ],
)

cc_test(
    name = "metric_example",
    srcs = glob([
        "src/ray/test/examples/metric_example.cc",
    ]),
    args = [
        "--ray_code_search_path $(location metric_example.so)",
    ],
    data = [
        "metric_example.so",
    ],
    linkstatic = True,
    tags = ["team:core"],
    deps = [
        "ray_cpp_lib",
        "@boost//:callable_traits",
        "@boost//:optional",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/flags:parse",
        "@msgpack",
        "@nlohmann_json",
    ],
)

cc_binary(
    name = "metric_example.so",
    testonly = True,
    srcs = glob([
        "src/ray/test/examples/metric_example.cc",
    ]),
    linkopts = ["-shared"],
    linkstatic = True,
    deps = [
        "ray_cpp_lib",
        "@boost//:callable_traits",
        "@boost//:optional",
        "@com_google_absl//absl/flags:flag",
        "@com_google_absl//absl/flags:parse",
        "@msgpack",
        "@nlohmann_json",
    ],
)

py_test_module_list(
    size = "medium",
    extra_srcs = [],
    files = [
        "test_python_call_cpp.py",
    ],
    tags = [
        "exclusive",
        "medium_size_python_tests",
        "team:core",
    ],
    deps = [],
)

py_test(
    name = "test_submit_cpp_job",
    size = "medium",
    srcs = ["test_submit_cpp_job.py"],
    data = [
        "simple_job",
        "simple_job.so",
    ],
    env = {
        "SIMPLE_DRIVER_SO_PATH": "$(location simple_job.so)",
        "SIMPLE_DRIVER_MAIN_PATH": "$(location simple_job)",
    },
    tags = ["team:core"],
)
